import { Command } from "commander";
import { Log, LogStatus, LogType } from "../../util/Logger";
import { BridgeConfig } from "../core/BridgeConfig";
import * as fs from "fs";
import { BridgeDirection, createProviders, initProviders } from "../core/ChainProviderFactory";

export type StressArgs = {
    direction: BridgeDirection;
    bridgeConfig: BridgeConfig;
    amount: number;
};

const parse = (args: any): StressArgs | undefined => {
    const validNumber = (n: any): boolean => !isNaN(Number(n)) && Number(n) >= 0;
    if (args.origin && (args.origin == "xrp" || args.origin == "evm") && args.config && validNumber(args.amount)) {
        return {
            direction: args.origin === "xrp" ? BridgeDirection.XRP_TO_EVM : BridgeDirection.EVM_TO_XRP,
            bridgeConfig: new BridgeConfig(JSON.parse(fs.readFileSync(args.config).toString())),
            amount: Number(args.amount),
        };
    }
    return undefined;
};

const program = new Command("create-account")
    .option("-o, --origin <xrp|evm>", "Origin chain to execute the claim")
    .option("-op, --origin-private-key <value>", "Origin private key")
    .option("-da, --destination-address <value>", "Destination address")
    .option("-c, --config <value>", "Exported bridge config json file")
    .option("-a, --amount <number>", "Amount")
    .action(async (args) => {
        const parsedArgs = parse(args);
        if (parsedArgs && args.destinationAddress && args.originPrivateKey) {
            const { bridgeConfig, direction } = parsedArgs;
            const providers = createProviders(direction, bridgeConfig);

            Log(LogType.Bridge, LogStatus.ToDo, `Initializing providers...`);
            await initProviders(providers);
            Log(LogType.Bridge, LogStatus.Done, `Providers initialized`);

            const sourceProvider = providers[direction].source;
            const destinationProvider = providers[direction].destination;

            Log(LogType.Bridge, LogStatus.ToDo, `Creating create account commit at address ${args.destinationAddress}...`);
            await sourceProvider.createAccount(
                args.originPrivateKey,
                args.amount || 50,
                destinationProvider.getOtherChainAddress(args.destinationAddress),
            );
            Log(LogType.Bridge, LogStatus.Done, "Create account commit transacted successfully");
            process.exit(0);
        } else {
            program.help();
            process.exit(1);
        }
    });
export default program;
